package io.youngledo.usb.connection;

import io.youngledo.usb.storage.StorageConfig;

import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 连接标识符生成器
 * 为不同类型的存储服务生成智能的显示名称
 */
public class ConnectionIdentifier {

    private static final Map<String, String> REGION_MAP = Map.of(
        "cn-beijing", "北京",
        "cn-shanghai", "上海",
        "cn-hangzhou", "杭州",
        "cn-shenzhen", "深圳",
        "cn-hongkong", "香港",
        "us-east-1", "美东1",
        "us-west-1", "美西1",
        "us-west-2", "美西2",
        "eu-west-1", "欧洲西部",
        "ap-southeast-1", "亚太东南1"
    );

    /**
     * 根据存储配置生成智能显示名称
     */
    public static String generateDisplayName(StorageConfig config) {
        String type = config.type().getDisplayName();
        String endpoint = config.endpoint();

        return switch (config.type()) {
            case MINIO -> type + " (" + extractHostPort(endpoint) + ")";
            case ALIYUN_OSS -> {
                String ossRegion = extractOSSRegion(endpoint);
                yield type + " (" + (ossRegion != null ? ossRegion : extractHostPort(endpoint)) + ")";
            }
            case TENCENT_COS -> {
                String cosRegion = extractCOSRegion(endpoint);
                yield type + " (" + (cosRegion != null ? cosRegion : extractHostPort(endpoint)) + ")";
            }
            case HUAWEI_OBS -> {
                String obsRegion = extractOBSRegion(endpoint);
                yield type + " (" + (obsRegion != null ? obsRegion : extractHostPort(endpoint)) + ")";
            }
            default -> throw new IllegalArgumentException("Unsupported storage type: " + config.type());
        };
    }

    /**
     * 提取主机名和端口
     */
    private static String extractHostPort(String endpoint) {
        // 移除协议前缀
        String result = endpoint.replaceAll("^https?://", "");

        // 如果是localhost或IP，保持原样
        if (result.startsWith("localhost") || result.matches("^\\d+\\.\\d+\\.\\d+\\.\\d+")) {
            return result;
        }

        // 对于域名，尝试提取有意义的部分
        String[] parts = result.split("\\.");
        if (parts.length >= 2) {
            return parts[0] + (result.contains(":") ? result.substring(result.lastIndexOf(":")) : "");
        }

        return result;
    }

    /**
     * 提取阿里云OSS区域信息
     */
    private static String extractOSSRegion(String endpoint) {
        // oss-cn-beijing.aliyuncs.com -> 北京
        Pattern pattern = Pattern.compile("oss-([^.]+)\\.aliyuncs\\.com");
        Matcher matcher = pattern.matcher(endpoint);

        if (matcher.find()) {
            String region = matcher.group(1);
            return REGION_MAP.getOrDefault(region, region);
        }

        return null;
    }

    /**
     * 提取腾讯云COS区域信息
     */
    private static String extractCOSRegion(String endpoint) {
        // cos.ap-beijing.myqcloud.com -> 北京
        Pattern pattern = Pattern.compile("cos\\.([^.]+)\\.myqcloud\\.com");
        Matcher matcher = pattern.matcher(endpoint);

        if (matcher.find()) {
            String region = matcher.group(1);
            return REGION_MAP.getOrDefault(region, region);
        }

        return null;
    }

    /**
     * 提取华为云OBS区域信息
     */
    private static String extractOBSRegion(String endpoint) {
        // obs.cn-north-4.myhuaweicloud.com -> cn-north-4
        Pattern pattern = Pattern.compile("obs\\.([^.]+)\\.myhuaweicloud\\.com");
        Matcher matcher = pattern.matcher(endpoint);

        if (matcher.find()) {
            String region = matcher.group(1);
            return REGION_MAP.getOrDefault(region, region);
        }

        return null;
    }

    /**
     * 确保连接名称的唯一性
     */
    public static String ensureUniqueName(String baseName, java.util.Set<String> existingNames) {
        if (!existingNames.contains(baseName)) {
            return baseName;
        }

        int counter = 2;
        String uniqueName;
        do {
            uniqueName = baseName + " (" + counter + ")";
            counter++;
        } while (existingNames.contains(uniqueName));

        return uniqueName;
    }
}